<?php

namespace App\Services\WeChat;

use App\Common\ApiErrorCode;
use App\Exceptions\ApiException;
use App\Models\Config;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class WeChatService
{
    protected $baseUrl = 'https://api.weixin.qq.com';
    protected $weChat, $miniAppId, $miniAppSecret;
    protected $grantType = 'authorization_code';
    protected $responseType = 'json';
    protected $scope = 'snsapi_base';
    protected $redirectUri;

    public function __construct()
    {
        $config = Config::getValue(['wx_mini_app_id', 'wx_mini_app_secret']);
        $this->miniAppId = $config['wx_mini_app_id'] ?: config('ymi.wx.mini_app_id');
        $this->miniAppSecret = $config['wx_mini_app_secret'] ?: config('ymi.wx.mini_app_secret');
    }


    /**
     * 通过code换取获取微信用户信息：openid、unionid、session_key
     */
    public function getWxInfoByCode($code)
    {
        $url = $this->baseUrl . '/sns/jscode2session';
        $params = [
            'appid' => $this->miniAppId,
            'secret' => $this->miniAppSecret,
            'js_code' => $code,
            'grant_type' => 'authorization_code'
        ];
        $res = Http::withoutVerifying()->get($url, $params)->json();
        if (empty($res['openid'])) {
            Log::error('getWxInfoByCode() error', $res);
            throw new ApiException(ApiErrorCode::WX_LOGIN_FAIL);
        }
        return $res;
    }

    /**
     * 获取微信绑定手机号信息
     * phoneNumber（国外手机号会有区号），purePhoneNumber（没有区号）
     */
    public function getWxPhoneInfo(string $code){
        $url = $this->baseUrl . '/wxa/business/getuserphonenumber?access_token='.$this->getAccessToken();
        $res = Http::withoutVerifying()->post($url, ['code'=>$code])->json();
        if($res['errcode'] != 0){
            Log::error('获取微信绑定手机号失败', $res);
            throw new ApiException(ApiErrorCode::WX_LOGIN_FAIL);
        }
        return $res['phone_info'];
    }

    /**
     * 获取微信access_token
     */
    public function getAccessToken()
    {
        return Cache::remember('wx_access_token1353', 5, function () {
            Log::info('getAccessToken过期重新获取');
            $url = $this->baseUrl . '/cgi-bin/token';
            $params = [
                'appid' => $this->miniAppId,
                'secret' => $this->miniAppSecret,
                'grant_type' => 'client_credential'
            ];
            $res = Http::withoutVerifying()->get($url, $params)->json();
            return $res['access_token'] ?? '';
        });
    }
}
